package anim;

import dae.Matrix;

public class Matrix3D
{

    public float data[][] = new float[4][4];

    private StringBuilder builder = new StringBuilder();
    private boolean dirty = true;

    public Matrix3D(Matrix matrix)
    {
        String ss[] = matrix.value.split(" ");
        if (ss.length == 16)
        {
            for (int i = 0; i < 16; i++)
            {
                data[i / 4][i % 4] = Float.parseFloat(ss[i]);
            }
            buildString();
        }
    }

    public Matrix3D(String value)
    {
        String ss[] = value.split(",");
        if (ss.length == 16)
        {
            for (int i = 0; i < 16; i++)
            {
                data[i / 4][i % 4] = Float.parseFloat(ss[i]);
            }
            buildString();
        }else
        {
            System.out.println("matrix length error");
        }
    }

    public Matrix3D()
    {
    }

    @Override
    public String toString()
    {
        if (dirty)
        {
            buildString();
            dirty = false;
        }
        return builder.toString();
    }

    private void buildString()
    {
        builder.delete(0, builder.length());
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                builder.append(data[i][j]);
                builder.append(" ");
            }
            builder.append(";");
        }
    }

    public void update(int i, int j, float value)
    {
        data[i][j] = value;
        dirty = true;
    }

    @Override
    protected Matrix3D clone()
    {
        Matrix3D copy = new Matrix3D();
        copy.dirty = true;
        for (int i = 0; i < data.length; i++)
        {
            copy.data[i] = data[i].clone();
        }
        return copy;
    }

    public Matrix3D multi(Matrix3D other)
    {
        Matrix3D re = new Matrix3D();
        calculateMatrixMulti(this.data, other.data, re.data);
        return re;
    }

    public static void calculateMatrixMulti(float[][] array1, float[][] array2, float[][] resultArray)
    {
        for (int i = 0; i < array1.length; i++)
        {
            for (int j = 0; j < array2[0].length; j++)
            {
                resultArray[i][j] = lineMultiColumn(i, j, array1, array2);
            }
        }
    }

    public static float lineMultiColumn(int line, int column, float[][] array1, float[][] array2)
    {
        int lineLength = array1[line].length;
        int columnLength = array1.length;
        if (lineLength != columnLength)
        {
            return 0;
        }
        float re = 0;
        for (int i = 0; i < lineLength; i++)
        {
            re += array1[line][i] * array2[i][column];
        }
        return re;
    }

    public static Matrix3D getOneMatrix()
    {
        return new Matrix3D(
                "1,0,0,0," +
                        "0,1,0,0," +
                        "0,0,1,0," +
                        "0,0,0,1");
    }
}
